<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <script>
    // arr.forEach((item,index,arr) {}) 循环遍历数组每一项
    // 无返回值，不改变原数组
    // 使用return语句跳出本次循环，执行下一次循环
    // 通过抛出异常的方式实现终止循环
    /* const arr = [5, 8, 6, 2, 9]
    arr.forEach(item => {
      // console.log(item);
      if(item === 2) {
        return
      }
      console.log(item); // 5 8 6 9
    }) */
    /* try {
      arr.forEach(item => {
        if(item === 2) {
          throw new Error('终止循环')
        }
        console.log(item); // 5 8 6
      })
    } catch (error) {
      console.log(error.message); // '终止循环'
    } */

    // 手写forEach方法
    /* Array.prototype.myforEach = function(fn) {
      for(let i = 0; i < this.length; i++) {
        fn(this[i],i,this)
      }
    }
    const arr = [5, 8, 6, 2, 9]
    arr.myforEach(item => {
      console.log(item);
    }) */

    // end


    // arr.map((item,index,arr) => {}) 遍历操作数组的每一项，并返回一个新数组
      // 不改变原数组
      // 如果不写return，返回的都是undefined
      /* const arr = [5, 8, 6, 2, 9]
      const newArr = arr.map((item) => {
        return item + 1
      })
      console.log(newArr); // [6, 9, 7, 3, 10]
      console.log(arr); // [5, 8, 6, 2, 9] */

      // 手写map方法
      /* Array.prototype.mymap = function(fn) {
        let newArr = []
        for(let i = 0;i < this.length; i++) {
          newArr.push(fn(this[i],i,this))
        }
        return newArr
      }
      const arr = [5, 8, 6, 2, 9]
      const newArr = arr.mymap((item) => {
        return item + 1
      })
      console.log(newArr);
      console.log(arr); */

    // end

    // arr.filter((item,index,arr) => {}) 过滤器,通过遍历数组的每一项来筛选符合条件的数组元素
      // 创建一个新数组并返回，不改变原数组
      /* const arr = [5, 8, 6, 2, 9]
      const newArr = arr.filter(item => item % 2 === 0)
      console.log(newArr); // [8, 6, 2]
      console.log(arr); // [5, 8, 6, 2, 9] */

      // 手写filter方法
      /* Array.prototype.myfilter = function(fn) {
        let newArr = []
        if (!this.length) return newArr
        for(let i = 0;i < this.length;i++) {
          // 根据函数返回值判断是否符合条件
          if(fn(this[i],i,this)) {
            newArr.push(this[i])
          }
        }
        return newArr
      }
      const arr = [5, 8, 6, 2, 9]
      const newArr = arr.myfilter(item => item % 2 === 0)
      console.log(newArr); // [8, 6, 2]
      console.log(arr); */

    // end


    // arr.reduce(function(累计值prev, item, [,index][,arr]){}[,起始值]) 累加器,不改变原数组
      // 如果有起始值，以起始值开始累计，累计值=起始值
      // 如果没有起始值，则累计值以数组的第一项作为起始值开始累计
      // 返回函数累计处理的结果，经常用于求和等
      /* const arr = [5, 8, 6, 2, 9]
      const re = arr.reduce((prev,item) => prev + item,0)
      console.log(re); // 30
      console.log(arr); // [5, 8, 6, 2, 9] */

      // reduce/includes数组去重
      /* const arr = [5, 8, 6, 2, 9, 5, 6, 8]
      const newArr = arr.reduce((prev,item) => {
        prev.includes(item) ? null : prev.push(item)
        return prev
      },[])
      console.log(newArr); //  [5, 8, 6, 2, 9]
      console.log(arr); // [5, 8, 6, 2, 9, 5, 6, 8] */

      // 计算数组元素出现的次数
      /* let arr = ['name','age','long','short','long','name','name'] 
      const newArr = arr.reduce((prev,item) => {
        if(prev[item]) {
          prev[item]++
        } else {
          prev[item] = 1
        }
        return prev
      },{})
      console.log(newArr); // {name: 3, age: 1, long: 2, short: 1} */

      // 手写reduce方法
      /* Array.prototype.myreduce = function(fn,start) {
        let total = start || this[0] // 有初始值使用初始值
        // 有初始值的话从0遍历， 否则从1遍历
        for(let i = start ? 0 : 1;i < this.length; i++) {
          total = fn(total,this[i],i,this)
        }
        return total
      }
      const arr = [5, 8, 6, 2, 9]
      const re = arr.myreduce((prev,item) => prev + item,0)
      console.log(re);
      console.log(arr); */

    // end 

    
    // includes()方法是用来判断一个数组是否包含一个指定的值
      // 返回一个布尔值，如果是返回 true，否则false。
      // 不改变原数组
      // 注意：对象数组不能使用includes方法来检测，空数组也无法调用includes。
      // const arr = [5, 8, 6, 2, 9]
      // console.log(arr.includes(2)); // true
      // console.log(arr.includes(3)); // false
    // end


    // some() 方法会依次遍历数组的每个元素
      // 如果有一个元素满足条件，则表达式返回true , 剩余的元素不会再执行检测
      // 如果没有满足条件的元素，则返回false
      // 不会对空数组进行检测
      // 不会改变原数组
      // const arr = [5, 8, 6, 2, 9]
      // console.log(arr.some(item => item > 9)); // false
      // console.log(arr.some(item => item > 8)); // true

      // 手写some方法
      /* Array.prototype.mysome = function(fn) {
        for(let i = 0;i < this.length;i++) {
          if(fn(this[i],i,this)) {
            return true
          }
        }
        return false
      } */
    // end

    
    // every() 方法遍历数组中每一项的数据
      // 如果数组中检测到有一个元素不满足，则整个表达式返回 false ，剩余的元素不会再进行检测
      // 如果所有元素都满足条件，则返回 true
      // 不会对空数组进行检测
      // 不会改变原数组
      // const arr = [5, 8, 6, 2, 9]
      // console.log(arr.every(item => item > 2)); // false
      // console.log(arr.every(item => item > 1)); // true

      // 手写every方法
      /* Array.prototype.myevery = function() {
        for(let i = 0;i < this.length;i++) {
          if(!fn(this[i],i,this)) {
            return false
          }
        }
        return true
      } */

    // end
  </script>
</body>

</html>